﻿using System;
using System.IO.MemoryMappedFiles;
using System.Text;
using System.Data;
using System.Data.SqlClient;
using System.Text.RegularExpressions;
using System.Web;
using System.Security.Cryptography;
using System.IO;
using ChannelVN.Cached.Config;

namespace ChannelVN.Cached.Common
{
    public class Lib
    {
        /// <summary>
        /// is web application?
        /// </summary>
        public static bool IsWebApp
        {
            get
            {
                return null != HttpContext.Current;
            }
        }

        /// <summary>
        /// Lấy 1 xâu ngẫu nhiên
        /// </summary>
        /// <param name="length">Số lượng ký tự</param>
        /// <returns>Xâu ngẫu nhiên</returns>
        public static string GetRamdomString(int length)
        {
            string temp = "";
            var myAlphabet = new[] { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z" };

            var rnd = new Random();
            for (var i = 0; i < length; i++)
            {
                temp += myAlphabet[rnd.Next(0, myAlphabet.Length - 1)];
            }
            return temp;
        }

        #region Convert method

        /// <summary>
        /// Chuyển đổi 1 giá trị sang kiểu Integer
        /// </summary>
        /// <param name="value">Giá trị cần chuyển đổi</param>
        /// <returns>Số kiểu Integer, nếu lỗi return int.MinValue</returns>
        public static int Object2Integer(object value)
        {
            if (null == value) return 0;
            try
            {
                return Convert.ToInt32(value);
            }
            catch
            {
                return 0;
            }
        }
        /// <summary>
        /// Chuyển đổi 1 giá trị sang kiểu Long
        /// </summary>
        /// <param name="value">Giá trị cần chuyển đổi</param>
        /// <returns>Số kiểu Long, nếu lỗi return long.MinValue</returns>
        public static long Object2Long(object value)
        {
            if (null == value) return 0;
            try
            {
                return Convert.ToInt64(value);
            }
            catch
            {
                return 0;
            }
        }
        /// <summary>
        /// Chuyển đổi 1 giá trị sang kiểu Double
        /// </summary>
        /// <param name="value">Giá trị cần chuyển đổi</param>
        /// <returns>Số kiểu Double, nếu lỗi return double.NaN</returns>
        public static double Object2Double(object value)
        {
            if (null == value) return 0;
            try
            {
                return Convert.ToDouble(value);
            }
            catch
            {
                return 0;
            }
        }
        /// <summary>
        /// Chuyển đổi 1 giá trị sang kiểu float
        /// </summary>
        /// <param name="value">Giá trị cần chuyển đổi</param>
        /// <returns>Số kiểu float, nếu lỗi return float.NaN</returns>
        public static float Object2Float(object value)
        {
            if (null == value) return 0;
            try
            {
                return float.Parse(value.ToString());
            }
            catch
            {
                return 0;
            }
        }
        /// <summary>
        /// Chuyển đổi 1 giá trị sang kiểu boolean
        /// </summary>
        /// <param name="value">Giá trị cần chuyển đổi</param>
        /// <returns>giá trị kiểu boolean, nếu lỗi return false</returns>
        public static bool Object2Boolean(object p)
        {
            if (null == p)
            {
                return false;
            }

                int value = 0;
                int.TryParse(p.ToString(), out value);
                if (value > 0)
                {
                    return true;
                }
                else
                {
                    bool result = false;
                    bool.TryParse(p.ToString(), out result);
                    return result;
                }
            
        }
        /// <summary>
        /// Chuyển đổi 1 giá trị sang kiểu DateTime
        /// </summary>
        /// <param name="value">Giá trị cần chuyển đổi</param>
        /// <returns>Số kiểu DateTime, nếu lỗi return DateTime.MinValue</returns>
        public static DateTime Object2DateTime(object value)
        {
            if (null == value) return DateTime.MinValue;
            try
            {
                return Convert.ToDateTime(value);
            }
            catch
            {
                return DateTime.MinValue;
            }
        }
        /// <summary>
        /// Chuyển đổi 1 giá trị sang kiểu string
        /// </summary>
        /// <param name="value">Giá trị cần chuyển đổi</param>
        /// <returns>Xâu cần lấy, nếu lỗi return rỗng</returns>
        public static string Object2String(object value)
        {
            if (null == value) return "";
            return Convert.ToString(value);
        }
        /// <summary>
        /// Chuyển đổi 1 xâu ngày tháng dạng dd/MM/yyyy sang ngày tháng
        /// </summary>
        /// <param name="value">Xâu nhập</param>
        /// <returns>Trả về kiểu DateTime cua ngày cần chuyển đổi (Nếu lỗi thì trả về DateTime.MinValue)</returns>
        public static DateTime String2Date(string value)
        {
            var temp = value;

            var date = temp.Substring(0, temp.IndexOf("/"));
            temp = temp.Substring(temp.IndexOf("/") + 1);
            var month = temp.Substring(0, temp.IndexOf("/"));
            var year = temp.Substring(temp.IndexOf("/") + 1);

            var months = new[] { "jan", "feb", "mar", "apr", "may", "jun", "jul", "aug", "sep", "oct", "nov", "dec" };
            try
            {
                return Convert.ToDateTime(date + " " + months[Convert.ToInt32(month) - 1] + " " + year);
            }
            catch
            {
                return DateTime.MinValue;
            }
        }

        #endregion

        #region Chuyen doi xau dang unicode co dau sang dang khong dau

        private const string KoDauChars =
            "aaaaaaaaaaaaaaaaaeeeeeeeeeeediiiiiooooooooooooooooouuuuuuuuuuuyyyyyAAAAAAAAAAAAAAAAAEEEEEEEEEEEDIIIOOOOOOOOOOOOOOOOOOOUUUUUUUUUUUYYYYYAADOOU";

        private const string UniChars =
            "àáảãạâầấẩẫậăằắẳẵặèéẻẽẹêềếểễệđìíỉĩịòóỏõọôồốổỗộơờớởỡợùúủũụưừứửữựỳýỷỹỵÀÁẢÃẠÂẦẤẨẪẬĂẰẮẲẴẶÈÉẺẼẸÊỀẾỂỄỆĐÌÍỈĨỊÒÓỎÕỌÔỒỐỔỖỘƠỜỚỞỠỢÙÚỦŨỤƯỪỨỬỮỰỲÝỶỸỴÂĂĐÔƠƯ";

        /// <summary>
        /// Chuyển đổi 1 xâu từ dạng unicode có dấu sang dạng unicode không dấu
        /// </summary>
        /// <param name="s">xâu unicode có dấu</param>
        /// <returns>xâu unicode không dấu đã convert</returns>
        public static string UnicodeToKoDau(string s)
        {
            var retVal = String.Empty;
            s = s.Trim();
            for (var i = 0; i < s.Length; i++)
            {
                var pos = UniChars.IndexOf(s[i].ToString());
                if (pos >= 0)
                    retVal += KoDauChars[pos];
                else
                    retVal += s[i];
            }
            return retVal;
        }

        /// <summary>
        /// Chuyển đổi 1 xâu từ dạng unicode có dấu sang dạng unicode không dấu và có gạch ngăn cách giữa mỗi từ
        /// </summary>
        /// <param name="s">xâu unicode có dấu</param>
        /// <returns>xâu unicode không dấu và có gạch ngăn cách giữa mỗi từ</returns>
        public static string UnicodeToKoDauAndGach(string s)
        {
            const string strChar = "abcdefghiklmnopqrstxyzuvxw0123456789 ";
            //string retVal = UnicodeToKoDau(s);
            //s = s.Replace("-", " ");
            s = s.Replace("–", "");
            s = s.Replace("  ", " ");
            s = UnicodeToKoDau(s.ToLower().Trim());
            var sReturn = "";
            for (var i = 0; i < s.Length; i++)
            {
                if (strChar.IndexOf(s[i]) <= -1) continue;
                if (s[i] != ' ')
                    sReturn += s[i];
                else if (i > 0 && s[i - 1] != ' ' && s[i - 1] != '-')
                    sReturn += "-";
            }

            return sReturn;
        }

        #endregion
        
        #region Encrypt

        public static string MD5Encrypt(string value)
        {
            if (string.IsNullOrEmpty(value)) return "";
            //Declarations
            Byte[] originalBytes;
            Byte[] encodedBytes;
            MD5 md5;

            //Instantiate MD5CryptoServiceProvider, get bytes for original password and compute hash (encoded password)
            md5 = new MD5CryptoServiceProvider();
            originalBytes = ASCIIEncoding.Default.GetBytes(value);
            encodedBytes = md5.ComputeHash(originalBytes);

            //Convert encoded bytes back to a 'readable' string
            return BitConverter.ToString(encodedBytes).Replace("-", "").ToLower();
        }

        #endregion

        #region Log to file

        public static void WriteLogToFile(string message)
        {
            var logFile = AppConfigs.LogFolder;
            if (string.IsNullOrEmpty(logFile)) return;
            if (IsWebApp)
            {
                logFile = HttpContext.Current.Server.MapPath(logFile);
            }
            if (!logFile.EndsWith(@"\")) logFile += @"\";
            logFile += DateTime.Now.ToString("ddMMyyyy") + ".txt";

            try
            {
                File.AppendAllText(logFile, DateTime.Now.ToString("dd/MM/yyyy, HH:mm:ss") + ": " + message);
            }
            catch (Exception)
            {
            }
        }
        public static void WriteLogToFile(Exception exception)
        {
            var logFile = AppConfigs.LogFolder;
            if (string.IsNullOrEmpty(logFile)) return;
            if (IsWebApp)
            {
                logFile = HttpContext.Current.Server.MapPath(logFile);
            }
            if (!logFile.EndsWith(@"\")) logFile += @"\";
            logFile += DateTime.Now.ToString("ddMMyyyy") + ".txt";

            try
            {
                File.AppendAllText(logFile, DateTime.Now.ToString("dd/MM/yyyy, HH:mm:ss") + ": " + exception.Message + "\n" + exception.StackTrace);
                if (null != exception.InnerException)
                {
                    File.AppendAllText(logFile, exception.InnerException.Message + "\n" + exception.InnerException.StackTrace);
                }
            }
            catch (Exception)
            {
            }
        }

        #endregion

        public static string CompressHtmlContent(string html)
        {
            var regRemoveComment = new Regex("\\s+//[^\\n\\r]+[\\n\\r]+");
            html = (new Regex("<script[^>]*>.*?</script>", RegexOptions.IgnoreCase | RegexOptions.Singleline)).Replace(html, delegate(Match m)
            {
                return regRemoveComment.Replace(m.Groups[0].Value, string.Empty);
            });

            html = Regex.Replace(html, "^\\s*", string.Empty, RegexOptions.Compiled |
                                  RegexOptions.Multiline);
            //html = Regex.Replace(html, "^\\s*", string.Empty, RegexOptions.Compiled |
            //                      RegexOptions.Multiline);
            html = Regex.Replace(html, "\\r\\n", string.Empty, RegexOptions.Compiled |
                              RegexOptions.Multiline);
            html = Regex.Replace(html, "<!--*.*?-->", string.Empty, RegexOptions.Compiled |
                              RegexOptions.Multiline);
            return html;
        }
    }
}
